package com.hyy.asm.protocol;

import com.google.gson.*;

import java.io.*;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;

public interface Serializer {

    <T> T deserialize(Class<T> clazz, byte[] bytes);
    <T> byte[] serialize(T obj);

    enum Algorithm implements  Serializer{

        JDK{
            @Override
            public <T> T deserialize(Class<T> clazz, byte[] bytes) {
                try {
                    ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
                    return (T) ois.readObject();
                } catch (IOException | ClassNotFoundException e) {
                    throw new RuntimeException("JDK返序列化失败",e);
                }

            }

            @Override
            public <T> byte[] serialize(T obj) {

                try {
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    ObjectOutputStream oos = new ObjectOutputStream(baos);
                    oos.writeObject(obj);
                    return baos.toByteArray();
                } catch (IOException e) {
                    throw new RuntimeException("JDK序列化失败",e);
                }


            }
        },
        JSON{
            @Override
            public <T> T deserialize(Class<T> clazz, byte[] bytes) {
                String json = new String(bytes, StandardCharsets.UTF_8);
                System.out.println(json);
                Gson gson = new GsonBuilder().registerTypeAdapter(Class.class, new ClassCodec()).create();
                return gson.fromJson(json,clazz);
            }

            @Override
            public <T> byte[] serialize(T obj) {
                Gson gson = new GsonBuilder().registerTypeAdapter(Class.class, new ClassCodec()).create();
                String json = gson.toJson(obj);
                return json.getBytes(StandardCharsets.UTF_8);
            }
        }
    }

    // 针对之前报出：不支持 Class类转json的异常 做处理
    class ClassCodec implements JsonSerializer<Class<?>>, JsonDeserializer<Class<?>> {
        @Override
        public Class<?> deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
            try {
                String str = json.getAsString();
                return Class.forName(str);

            } catch (ClassNotFoundException e) {

                throw new JsonParseException(e);
            }
        }

        @Override
        public JsonElement serialize(Class<?> src, Type type, JsonSerializationContext jsonSerializationContext) {

            // JsonPrimitive 转化基本数据类型
            return new JsonPrimitive(src.getName());
        }
    }
}
